#include <iostream>
#include <typeinfo>
#include "aobject.hpp"
//debug
#include "obj_manager.hpp"

AObject::AObject() : _state(UNDEFINED), _linked(false), _type(OPERATOR)
{
  static unsigned int	current_id = 0;

  _id = current_id++;
}

unsigned int		AObject::getId() const
{
  return this->_id;
}

void			AObject::addObject(AObject* obj)
{
  if (obj)
    {
      ObjManager::displayThis(this);
      std::cout << "==>";
      ObjManager::displayThis(obj);
      std::cout << std::endl;
      this->_cond.push(obj);
    }
}

state			AObject::getState() const
{
  return this->_state;
}

AObject::type		AObject::getType() const
{
  return this->_type;
}

bool			AObject::link(LinkChain lk, LinkChainIterator lk_it)
{
  LinkChainIterator	previous = lk_it;
  LinkChainIterator	next = lk_it;

  ++next;
  --previous;
  if (previous == lk_it)
    previous = lk->end();
  if (previous == next || next == lk_it)
    {
      ObjManager::displayThis((lk_it->second).first);
      std::cout << " linkProblem" << std::endl;
    }
  return this->behaviour(lk, lk_it, previous, next);
}

bool			AObject::behaviour(LinkChain lk, LinkChainIterator lk_it,
					   LinkChainIterator prev, LinkChainIterator next)
{
  if (prev != lk->end() && next != lk->end())
    {
      if (((prev->second).first)->getType() == EQUAL
	  || ((next->second).first)->getType() == EQUAL)
	return false;
      ((lk_it->second).first)->addObject((prev->second).first);
      ((prev->second).first)->getRequiredLinks(lk, prev, lk_it);
      ((lk_it->second).first)->addObject((next->second).first);
      ((next->second).first)->getRequiredLinks(lk, next, lk_it);
      return true;
    }
  return false;
}

void			AObject::getRequiredLinks(LinkChain lk, LinkChainIterator lk_it, LinkChainIterator caller)
{
  LinkChainIterator	previous = lk_it;
  LinkChainIterator	next = lk_it;

  next = ++next;
  previous = --previous;
  if (next == caller)
    next = lk->end();
  if (previous == caller)
    previous = lk->end();
  this->behaviour(lk, lk_it, previous, next);
  (lk_it->second).second = true;
}
